package com.cai310.lottery.ticket.protocol.local.disassemble;

import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cai310.lottery.Constant;
import com.cai310.lottery.common.Lottery;
import com.cai310.lottery.common.SalesMode;
import com.cai310.lottery.support.dlt.DltCompoundContent;
import com.cai310.lottery.support.dlt.DltPlayType;
import com.cai310.lottery.support.el11to5.El11to5CompoundContent;
import com.cai310.lottery.support.el11to5.El11to5PlayType;
import com.cai310.lottery.ticket.common.StringOfListUtil;
import com.cai310.lottery.ticket.dto.PrintInterfaceDTO;
import com.cai310.lottery.ticket.dto.TicketDTO;
import com.cai310.lottery.ticket.protocol.DanTuoDataConver;
import com.cai310.utils.JsonUtil;

public class El11to5Disassemble extends AbstractDisassemble {
	private static final String NUMCODE = ",";
	private static final String CONTENTCONNECTCODE = "-";
	private static final String DANSPLITCODE = ":";
	private static final String SINGSPILTCODE = "+";
	private static final NumberFormat TWO_NF = new DecimalFormat("00");
	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	protected int getMaxMultiple() {
		return 99;
	}

	@Override
	protected int getMaxUnitsKeno() {
		return 5;
	}

	@Override
	protected int getMaxUnitsCommon() {
		return 5;
	}

	@Override
	protected List<TicketDTO> doCompound(PrintInterfaceDTO printData, Date createTime)
			throws Exception {
		List<TicketDTO> resultList = new ArrayList<TicketDTO>();
		TicketDTO ticketNew = null;
		String[] contents = JsonUtil.getStringArray4Json(printData.getContent());
		El11to5PlayType playType = El11to5PlayType.values()[printData.getBetType()];
		List<String> resultNewConverList = new ArrayList<String>();
		for(String content:contents){
			Byte BetType=null;
			Integer PlayType=null;
			StringBuffer BetContent = new StringBuffer();
			El11to5CompoundContent  compoundContent = JsonUtil.getObject4JsonString(content, El11to5CompoundContent.class);
			if(printData.getBetType()==El11to5PlayType.RandomEight.ordinal()){//任8
				BetType=7;
				PlayType=1;
				List<String> betDanList = StringOfListUtil.format(compoundContent.getBetDanList());
				List<String> betList = StringOfListUtil.format(compoundContent.getBetList());
				DanTuoDataConver bb = new DanTuoDataConver(playType.getLineLimit(), betDanList, betList);
				List<List<String>> resultConverList = bb.getResultList();
				for (List<String> bets : resultConverList) {
					resultNewConverList.add(StringUtils.join(bets, NUMCODE));
				}
				ticketNew = createTicketDTONew(printData, resultNewConverList,BetType,PlayType);
				if (ticketNew.getUnits() > getMaxUnitsKeno()) {
					resultList.addAll(doSingle(ticketNew));
				} else {
					resultList.add(ticketNew);
				}
			}else{
				if(1==compoundContent.getUnits()){
					//转单式
					PlayType=1;
					if(printData.getBetType()==El11to5PlayType.ForeThreeDirect.ordinal()){//直3
						 BetType=11;
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet1List(),TWO_NF),  NUMCODE));
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet2List(),TWO_NF),  NUMCODE));
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet3List(),TWO_NF),  NUMCODE));
					}else if(printData.getBetType()==El11to5PlayType.ForeTwoDirect.ordinal()){//直2
						 BetType=9;
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet1List(),TWO_NF),  NUMCODE));
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet2List(),TWO_NF),  NUMCODE));
					}else{
						if(printData.getBetType()==El11to5PlayType.NormalOne.ordinal()){
							BetType=0;
							PlayType=0;
						}else if(printData.getBetType()==El11to5PlayType.RandomTwo.ordinal()){
							BetType=1;
						}else if(printData.getBetType()==El11to5PlayType.RandomThree.ordinal()){
							BetType=2;
						}else if(printData.getBetType()==El11to5PlayType.RandomFour.ordinal()){
							BetType=3;
						}else if(printData.getBetType()==El11to5PlayType.RandomFive.ordinal()){
							BetType=4;
						}else if(printData.getBetType()==El11to5PlayType.RandomSix.ordinal()){
							BetType=5;
						}else if(printData.getBetType()==El11to5PlayType.RandomSeven.ordinal()){
							BetType=6;
						}else if(printData.getBetType()==El11to5PlayType.ForeTwoGroup.ordinal()){
							BetType=8;
						}else if(printData.getBetType()==El11to5PlayType.ForeThreeGroup.ordinal()){
							BetType=10;
						}
						BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBetDanList(),TWO_NF),  NUMCODE));
						BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBetList(),TWO_NF),  NUMCODE));
					}
				}else{
					PlayType=2;
					if(printData.getBetType()==El11to5PlayType.ForeThreeDirect.ordinal()){//直3
						 BetType=11;
						 PlayType=5;
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet1List(),TWO_NF),  NUMCODE)).append(CONTENTCONNECTCODE);
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet2List(),TWO_NF),  NUMCODE)).append(CONTENTCONNECTCODE);
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet3List(),TWO_NF),  NUMCODE));
					}else if(printData.getBetType()==El11to5PlayType.ForeTwoDirect.ordinal()){//直2
						 BetType=9;
						 PlayType=5;
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet1List(),TWO_NF),  NUMCODE)).append(CONTENTCONNECTCODE);
						 BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBet2List(),TWO_NF),  NUMCODE));
					}else{
						if(printData.getBetType()==El11to5PlayType.NormalOne.ordinal()){
							BetType=0;
							PlayType=0;
							BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBetDanList(),TWO_NF),  NUMCODE));
							BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBetList(),TWO_NF),  NUMCODE));
						}else{
							if(printData.getBetType()==El11to5PlayType.RandomTwo.ordinal()){
								BetType=1;
							}else if(printData.getBetType()==El11to5PlayType.RandomThree.ordinal()){
								BetType=2;
							}else if(printData.getBetType()==El11to5PlayType.RandomFour.ordinal()){
								BetType=3;
							}else if(printData.getBetType()==El11to5PlayType.RandomFive.ordinal()){
								BetType=4;
							}else if(printData.getBetType()==El11to5PlayType.RandomSix.ordinal()){
								BetType=5;
							}else if(printData.getBetType()==El11to5PlayType.RandomSeven.ordinal()){
								BetType=6;
							}else if(printData.getBetType()==El11to5PlayType.ForeTwoGroup.ordinal()){
								BetType=8;
							}else if(printData.getBetType()==El11to5PlayType.ForeThreeGroup.ordinal()){
								BetType=10;
							}
							BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBetDanList(),TWO_NF),  NUMCODE)).append(DANSPLITCODE);
							BetContent.append(StringUtils.join(formatBetNum(compoundContent.getBetList(),TWO_NF),  NUMCODE));
						}
					}
				}
				this.createTicketDTONew(resultList, printData, BetContent.toString(), compoundContent.getUnits(), BetType, PlayType);
			}
		}
		return resultList;
	}
	/**
	 * 单式内容拆单操作 可由子类覆写做相应的格式化操作
	 */
	@Override
	protected List<TicketDTO> doSingle(PrintInterfaceDTO printData, Date createTime) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		List<TicketDTO> resultList = new ArrayList<TicketDTO>();
		TicketDTO ticketNew = null;
		Byte BetType=null;
		Integer PlayType=1;
		if(printData.getBetType()==El11to5PlayType.RandomTwo.ordinal()){
			BetType=1;
		}else if(printData.getBetType()==El11to5PlayType.RandomThree.ordinal()){
			BetType=2;
		}else if(printData.getBetType()==El11to5PlayType.RandomFour.ordinal()){
			BetType=3;
		}else if(printData.getBetType()==El11to5PlayType.RandomFive.ordinal()){
			BetType=4;
		}else if(printData.getBetType()==El11to5PlayType.RandomSix.ordinal()){
			BetType=5;
		}else if(printData.getBetType()==El11to5PlayType.RandomSeven.ordinal()){
			BetType=6;
		}else if(printData.getBetType()==El11to5PlayType.RandomEight.ordinal()){
			BetType=7;
		}else if(printData.getBetType()==El11to5PlayType.ForeTwoGroup.ordinal()){
			BetType=8;
		}else if(printData.getBetType()==El11to5PlayType.ForeThreeGroup.ordinal()){
			BetType=10;
		}else if(printData.getBetType()==El11to5PlayType.ForeThreeDirect.ordinal()){//直3
			 BetType=11;
		}else if(printData.getBetType()==El11to5PlayType.ForeTwoDirect.ordinal()){//直2
			 BetType=9;
		}
		int maxUnits = Lottery.isKeno(printData.getLotteryType()) ? this.getMaxUnitsKeno() : this.getMaxUnitsCommon();
		if (printData.getUnits() > maxUnits) {
			String[] arr = printData.getContent().split("(\r\n|\n)+");
			int units = 0;
			List<String> contentList = new ArrayList<String>();
			for (String line : arr) {
				contentList.add(StringUtils.join(line.split(Constant.SINGLE_SEPARATOR_FOR_NUMBER), NUMCODE));
				units++;
				if (units == maxUnits) {
					ticketNew = new TicketDTO();
					PropertyUtils.copyProperties(ticketNew, printData);
					ticketNew.setId(null);
					ticketNew.setPrintinterfaceId(printData.getId());
					ticketNew.setCreateTime(createTime);
					ticketNew.setUnits(units);
					ticketNew.setSchemeCost(units * unitsMoney * ticketNew.getMultiple());
					ticketNew.setContent(StringUtils.join(contentList, SINGSPILTCODE));
					ticketNew.setBetType(BetType);
					ticketNew.setExtension(""+PlayType);
					resultList.addAll(this.doMultiple(ticketNew));
					units = 0;// 计数复位
					contentList.clear();// 重置
				}
			}
			if (units > 0) {
				ticketNew = new TicketDTO();
				PropertyUtils.copyProperties(ticketNew, printData);
				ticketNew.setId(null);
				ticketNew.setPrintinterfaceId(printData.getId());
				ticketNew.setCreateTime(createTime);
				ticketNew.setUnits(units);
				ticketNew.setBetType(BetType);
				ticketNew.setExtension(""+PlayType);
				ticketNew.setSchemeCost(units * unitsMoney * ticketNew.getMultiple());
				ticketNew.setContent(StringUtils.join(contentList, SINGSPILTCODE));
				resultList.addAll(this.doMultiple(ticketNew));
			}
		} else {
			ticketNew = new TicketDTO();
			PropertyUtils.copyProperties(ticketNew, printData);
			String[] arr = printData.getContent().split("(\r\n|\n)+");
			List<String> contentList = new ArrayList<String>();
			for (String line : arr) {
				contentList.add(StringUtils.join(line.split(Constant.SINGLE_SEPARATOR_FOR_NUMBER), NUMCODE));
			}
			ticketNew.setContent(StringUtils.join(contentList, SINGSPILTCODE));
			ticketNew.setId(null);
			ticketNew.setBetType(BetType);
			ticketNew.setExtension(""+PlayType);
			ticketNew.setPrintinterfaceId(printData.getId());
			ticketNew.setCreateTime(createTime);
			resultList.addAll(this.doMultiple(ticketNew));
		}
		return resultList;
	}
	/**
	 * 
	 * @param printData
	 * @param createTime
	 * @param contentList
	 * @param playType
	 * @return
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	private void createTicketDTONew(List<TicketDTO> resultList ,PrintInterfaceDTO printData,String content,Integer units,Byte betType,Integer playType) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
		TicketDTO ticketNew = new TicketDTO();
		PropertyUtils.copyProperties(ticketNew, printData);
		ticketNew.setId(null);
		ticketNew.setPrintinterfaceId(printData.getId());
		ticketNew.setContent(content);
		ticketNew.setUnits(units);
		ticketNew.setBetType(betType);
		ticketNew.setExtension(""+playType);
		ticketNew.setSchemeCost(units * unitsMoney * ticketNew.getMultiple());
		ticketNew.setCreateTime(new Date());
		resultList.addAll(super.doMultiple(ticketNew));
	}
	
	private TicketDTO createTicketDTONew(PrintInterfaceDTO printData, List<String> contentList,Byte BetType,Integer PlayType) throws IllegalAccessException,
	InvocationTargetException, NoSuchMethodException {
		String content = StringUtils.join(contentList,SINGSPILTCODE);
		int units = contentList.size();
		TicketDTO ticketNew = new TicketDTO();
		PropertyUtils.copyProperties(ticketNew, printData);
		ticketNew.setId(null);
		ticketNew.setPrintinterfaceId(printData.getId());
		ticketNew.setBetType(BetType);
		ticketNew.setExtension(""+PlayType);
		ticketNew.setContent(content);
		ticketNew.setUnits(units);
		ticketNew.setMultiple(printData.getMultiple());
		ticketNew.setSchemeCost(units * unitsMoney * ticketNew.getMultiple());
		ticketNew.setCreateTime(new Date());
		ticketNew.setMode(SalesMode.SINGLE);
		return ticketNew;
	}
	public List<TicketDTO> doSingle(TicketDTO ticket) throws IllegalAccessException, InvocationTargetException,
		NoSuchMethodException {
		List<TicketDTO> resultList = new ArrayList<TicketDTO>();
		TicketDTO ticketNew = null;
		int maxUnits = Lottery.isKeno(ticket.getLotteryType()) ? this.getMaxUnitsKeno() : this.getMaxUnitsCommon();
		if (ticket.getUnits() > maxUnits) {
			String[] arr = ticket.getContent().split("\\"+SINGSPILTCODE);
			int units = 0;
			List<String> contentList = new ArrayList<String>();
			for (String line : arr) {
				contentList.add(line);
				units++;
				if (units == maxUnits) {
					ticketNew = new TicketDTO();
					PropertyUtils.copyProperties(ticketNew, ticket);
					ticketNew.setId(null);
					ticketNew.setPrintinterfaceId(ticket.getPrintinterfaceId());
					ticketNew.setCreateTime(ticket.getCreateTime());
					ticketNew.setUnits(units);
					ticketNew.setSchemeCost(units * unitsMoney * ticketNew.getMultiple());
					ticketNew.setContent(StringUtils.join(contentList, SINGSPILTCODE));
					resultList.addAll(this.doMultiple(ticketNew));
					units = 0;// 计数复位
					contentList.clear();// 重置
				}
			}
			if (units > 0) {
				ticketNew = new TicketDTO();
				PropertyUtils.copyProperties(ticketNew, ticket);
				ticketNew.setId(null);
				ticketNew.setPrintinterfaceId(ticket.getPrintinterfaceId());
				ticketNew.setCreateTime(ticket.getCreateTime());
				ticketNew.setUnits(units);
				ticketNew.setSchemeCost(units * unitsMoney * ticketNew.getMultiple());
				ticketNew.setContent(StringUtils.join(contentList, SINGSPILTCODE));
				resultList.addAll(this.doMultiple(ticketNew));
			}
		} else {
			resultList.addAll(this.doMultiple(ticketNew));
		}
		return resultList;
	}
	
}
